import PlayerEntity from "../entity/PlayerEntity";
type ElementMethod = () => void;

export class RandomSelector {
    private elements: Array<PlayerEntity> = [];
    private remainingIndices: number[];
    private timer: NodeJS.Timeout | null = null;
    private isRunning = false;
    private readonly minDelay: number;
    private readonly maxDelay: number;
    private firstDelay: number | null;
    private isDestroyed = false;

    constructor(
        elements: PlayerEntity[],
        private onComplete: () => void,
        minDelay: number = 200,
        maxDelay: number = 2000,
        firstDelay: number | null = null
    ) {
        if (elements.length === 0) throw new Error("Array must contain elements");
        if (minDelay >= maxDelay) throw new Error("Invalid delay range");
        if (firstDelay !== null && firstDelay < 0) throw new Error("First delay must be non-negative");

        this.elements = [...elements];
        this.remainingIndices = Array.from({ length: elements.length }, (_, i) => i);
        this.minDelay = minDelay;
        this.maxDelay = maxDelay;
        this.firstDelay = firstDelay;
    }

    start(): void {
        if (this.isDestroyed) throw new Error("Cannot start a destroyed selector");
        if (this.isRunning) return;
        this.isRunning = true;
        // 如果有设置第一个元素的延迟时间
        if (this.firstDelay !== null && this.remainingIndices.length === this.elements.length) {
            this.timer = setTimeout(() => {
                this.selectAndExecute();
            }, this.firstDelay);
        } else {
            this.scheduleNext();
        }
    }

    private scheduleNext(): void {
        if (!this.isRunning || this.remainingIndices.length === 0) return;

        const delay = Math.floor(
            Math.random() * (this.maxDelay - this.minDelay + 1) + this.minDelay
        );

        this.timer = setTimeout(() => {
            this.selectAndExecute();
        }, delay);
    }

    private selectAndExecute(): void {
        if (this.remainingIndices.length === 0) return;

        const randomIndex = Math.floor(Math.random() * this.remainingIndices.length);
        const elementIndex = this.remainingIndices[randomIndex];

        // 移除已选索引
        this.remainingIndices.splice(randomIndex, 1);
        // 执行元素方法
        this.elements[elementIndex].playerFakeReady();

        // 检查是否全部完成
        if (this.remainingIndices.length === 0) {
            this.isRunning = false;
            this.onComplete();
            this.destroy();
        }
        else {
            this.scheduleNext();
        }
    }

    cancel(): void {
        if (this.isDestroyed) throw new Error("Cannot start a destroyed selector");
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
        }
        this.isRunning = false;
    }

    reset(): void {
        this.cancel();
        this.remainingIndices = Array.from(
            { length: this.elements.length },
            (_, i) => i
        );
    }

    // 销毁实例，清理所有资源
    destroy(): void {
        if (this.isDestroyed) return;

        // 清除定时器
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
        }

        // 标记为已销毁
        this.isDestroyed = true;
        this.isRunning = false;

        // 清除所有引用以帮助垃圾回收
        this.elements = [];
        this.remainingIndices = [];

        // 可选：移除完成回调引用
        this.onComplete = () => { };
    }

}

